#include "ball.h"

#include <QPainter>
#include <QMimeData>
#include <QGraphicsSceneMouseEvent>
#include <QApplication>
#include <QDrag>
#include <QBitmap>
#include <QGraphicsScene>
#include <QDebug>
#include <QList>
#include <qmath.h>

#include "board.h"

Ball::Ball(Place* place) :
    _lastPlace(0),
    _prevPlace(place),
    _lastAvailable(false)
{
    setPos(place->pos());
    setFlag(ItemIsMovable, true);
    setFlag(ItemSendsScenePositionChanges, true);
}

const int RADIUS = 10;

QRectF Ball::boundingRect() const
{
    return QRectF(-RADIUS * 2, -RADIUS * 2, 4 * RADIUS, 4 * RADIUS);
}

void Ball::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*)
{
    painter->setBrush(Qt::black);
    painter->drawEllipse(-RADIUS, -RADIUS, 2 * RADIUS, 2 * RADIUS);
}

QVariant Ball::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == ItemPositionChange && scene()) {
        Place* place = 0;
        QPointF newPos = value.toPointF();
        QList<QGraphicsItem*> intersectsItems = scene()->collidingItems(this, Qt::IntersectsItemBoundingRect);
        for (QList<QGraphicsItem*>::iterator it = intersectsItems.begin(); it != intersectsItems.end(); ++it) {
             place = dynamic_cast<Place*>(*it);
            if (place != 0 && place != _prevPlace) {
                QPointF offset = place->pos() - newPos;
                int distance = qSqrt(offset.x() * offset.x() + offset.y() * offset.y());

                if (distance < RADIUS) {
                    _lastAvailable = ((Board*)scene())->get(place->row(), place->col()) == F &&
                            ((place->row() == _prevPlace->row() && qAbs(place->col() - _prevPlace->col()) == 2 &&
                                ((Board*)scene())->get(place->row(), (place->col() + _prevPlace->col()) / 2) == O) ||
                             (place->col() == _prevPlace->col() && qAbs(place->row() - _prevPlace->row()) == 2 &&
                                ((Board*)scene())->get((place->row() + _prevPlace->row()) / 2, place->col()) == O));

                    place->setColor(_lastAvailable ? Qt::green : Qt::red);
                    break;
                } else  {
                    place = 0;
                }
            }
        }

        if (place != _lastPlace && _lastPlace != 0) {
            _lastPlace->setColor(Qt::transparent);
            _lastPlace->update();
        }

        _lastPlace = place;
    }
    return QGraphicsItem::itemChange(change, value);
}

void Ball::makeStep()
{
    this->setPos(_lastPlace->pos());
    _lastPlace->setColor(Qt::transparent);

    ((Board*)scene())->set(_prevPlace->row(), _prevPlace->col(), F);
    ((Board*)scene())->set(_lastPlace->row(), _lastPlace->col(), O);

    int dropRow = (_prevPlace->row() + _lastPlace->row()) / 2;
    int dropCol = (_prevPlace->col() + _lastPlace->col()) / 2;
    ((Board*)scene())->set(dropRow, dropCol, F);

    int dropX = (_prevPlace->x() + _lastPlace->x()) / 2;
    int dropY = (_prevPlace->y() + _lastPlace->y()) / 2;
    scene()->itemAt(dropX, dropY)->hide();

    _prevPlace = _lastPlace;
}

void Ball::cancelStep()
{
    setPos(_prevPlace->pos());
}

void Ball::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (_lastPlace != 0 && _lastAvailable) {
        makeStep();
    } else {
        cancelStep();
    }

    _lastPlace = 0;

    ((Board*)scene())->print();

    QGraphicsItem::mouseReleaseEvent(event);
}
